package com.vichat.common.signal;

import com.alibaba.fastjson.JSON;
import com.vichat.common.cache.CacheManagerRedis;
import com.vichat.common.cache.RedisKey;
import com.vichat.common.enums.CommonConst;
import com.vichat.common.rudp.RudpCmdDefine;
import com.vichat.common.rudp.RudpDataUtil;
import com.vichat.common.rudp.RudpParamDefine;
import com.vichat.common.rudp.RudpSendresSrvImpl;
import com.vichat.common.rudp.thread.RudpReceiveDataManager;
import com.vichat.common.rudp.thread.RudpSendDataManager;
import com.vichat.common.signal.bean.CommonNotify;
import com.vichat.common.signal.bean.ServiceDefine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.*;
import java.util.concurrent.*;

public class SignalCmdUtil {

    protected static transient final Logger log = LoggerFactory.getLogger(SignalCmdUtil.class);

    private static transient List<ServiceDefine> sgsDeploys = null;
    private static transient List<ServiceDefine> imsDeploys = null;
    private static transient List<ServiceDefine> showDeploys = null;

    private static final Object locker = new Object(), lockerSgs = new Object(), lockerShow = new Object();
    private static int msgid = 0;

    public static void initSignalClient() {
        initSignalClient(18621);
    }

    public static boolean IS_SEND_BY_EXT_IP = false;

    public static void initSignalClient(int port) {
        try {
            String hostname = "0.0.0.0";
            InetAddress address = InetAddress.getByName(hostname);
            SocketAddress socketAddress = new InetSocketAddress(address, port);
            RudpDataUtil.initSocket(socketAddress);
        } catch (Exception e) {
            log.error("初始化客户端socket失败", e);
        }
    }

    public static void reloadDeploys() throws Exception {
        synchronized (locker) {
            sgsDeploys = getServiceDeploys("sgs");
            imsDeploys = getServiceDeploys("ims");
            showDeploys = getServiceDeploys("show");
        }
    }

    public static void loadImsDeploys() throws Exception {
        if (imsDeploys != null) {
            return;
        }
        synchronized (locker) {
            if (imsDeploys != null) {
                return;
            }
            imsDeploys = getServiceDeploys("ims");
        }
    }

    public static void loadSgsDeploys() throws Exception {
        if (sgsDeploys != null) {
            return;
        }
        synchronized (lockerSgs) {
            if (sgsDeploys != null) {
                return;
            }
            sgsDeploys = getServiceDeploys("sgs");
        }
    }

    public static void loadShowDeploys() throws Exception {
        if (showDeploys != null) {
            return;
        }
        synchronized (lockerShow) {
            if (showDeploys != null) {
                return;
            }
            showDeploys = getServiceDeploys("show");
        }
    }

    private static List<ServiceDefine> getServiceDeploys(String srvType) throws Exception {
        List<ServiceDefine> serviceList = null;
        CacheManagerRedis redis = CacheManagerRedis.getWebInstance();
        Set<String> srvs = redis.smembers(RedisKey.Service.SERVICE_CFG, srvType);
        if (srvs != null && srvs.size() > 0) {
            serviceList = new ArrayList<>();
            for (String srv : srvs) {
                log.info("###########" + srv);
                if (srv != null && !"".equals(srv)) {
                    serviceList.add(JSON.parseObject(srv, ServiceDefine.class));
                }
            }
        }
        return serviceList;
    }

    public static Map<Integer, String> sendImsCmd(HashMap<Integer, String> param, boolean async, long srvId) throws Exception {
        loadImsDeploys();
        if (imsDeploys == null) {
            throw new Exception("服务列表为空，请刷新REDIS缓存");
        }

        log.info("\n@@@@@@@@@@@@@@@@@调用ims服务@@@@@@@@@@@@\n ims 服务列表 " + imsDeploys.toString() + "\n调用报文" + param.toString());
        if (srvId > 0) {
            for (ServiceDefine define : imsDeploys) {
                if (define.srvId.equals(String.valueOf(srvId))) {
                    return sendDataSingle(param, async, define);
                }
            }
        }
        return sendData(param, async, imsDeploys);
    }

    public static Map<Integer, String> sendSgsCmd(HashMap<Integer, String> param, boolean async, long srvId) throws Exception {
        loadSgsDeploys();
        if (sgsDeploys == null) {
            throw new Exception("服务列表为空，请刷新REDIS缓存");
        }
        log.info("\n@@@@@@@@@@@@@@@@@调用sgs服务@@@@@@@@@@@@\n sgs 服务列表 " + sgsDeploys.toString() + "\n调用报文" + param.toString());
        if (srvId > 0) {
            for (ServiceDefine define : sgsDeploys) {
                if (define.srvId.equals(String.valueOf(srvId))) {
                    return sendDataSingle(param, async, define);
                }
            }
        }
        return sendData(param, async, sgsDeploys);
    }

    public static Map<Integer, String> sendShowCmd(HashMap<Integer, String> param, boolean async, long srvId) throws Exception {
        loadShowDeploys();

        showDeploys = new ArrayList<>();
//        showDeploys.add(JSON.parseObject("{\"clusterId\":0,\"extIp\":\"192.168.0.105\",\"intIp\":\"192.168.0.105\",\"srvId\":\"1\",\"srvPort\":8005,\"srvType\":\"show\"}", ServiceDefine.class));
        showDeploys.add(JSON.parseObject("{\"clusterId\":0,\"extIp\":\"61.191.61.2\",\"intIp\":\"61.191.61.2\",\"srvId\":\"1031\",\"srvPort\":8005,\"srvType\":\"show\"}", ServiceDefine.class));

        if (showDeploys == null) {
            throw new Exception("服务列表为空，请刷新REDIS缓存");
        }
        log.info("\n@@@@@@@@@@@@@@@@@调用show服务@@@@@@@@@@@@\n show 服务列表 " + showDeploys.toString() + "\n调用报文" + param.toString());
        if (srvId > 0) {
            for (ServiceDefine define : showDeploys) {
                if (define.srvId.equals(String.valueOf(srvId))) {
                    return sendDataSingle(param, async, define);
                }
            }
        }
        return sendData(param, async, showDeploys);
    }

    public static Map<Integer, String> sendShowCmd(HashMap<Integer, String> param, ServiceDefine serviceDefine) throws Exception {
        List showDeploys = new ArrayList<>();
        showDeploys.add(serviceDefine);

        log.info("\n@@@@@@@@@@@@@@@@@调用show服务@@@@@@@@@@@@\n show 服务列表 " + showDeploys.toString() + "\n调用报文" + param.toString());

        return sendData(param, false, showDeploys);
    }

    public static int mediaRecord(long rid, long uid,String refId, String cmd,ServiceDefine serviceDefine) throws Exception {
        HashMap<Integer, String> req = new HashMap<>();
        req.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_admin_req));
        req.put(RudpParamDefine.cmd_param_subcmd, cmd);
        req.put(RudpParamDefine.cmd_param_rid, String.valueOf(rid));
        req.put(RudpParamDefine.cmd_param_uid, String.valueOf(uid));
        req.put(RudpParamDefine.cmd_param_ref_id, refId);
        req.put(RudpParamDefine.cmd_param_time_len, "8");
        req.put(RudpParamDefine.cmd_param_count, "3");

        Map<Integer, String> map = SignalCmdUtil.sendShowCmd(req,serviceDefine);
        return checkMap(map);
    }


    private static Map<Integer, String> sendData(HashMap<Integer, String> param, boolean async, List<ServiceDefine> deploys) {
        Map<Integer, String> rtn = null;
        for (ServiceDefine srvDefine : deploys) {
            try {
                Map<Integer, String> map = sendDataSingle(param, async, srvDefine);
                if (map != null && checkMap(map) == 0) {
                    rtn = map;
                }
            } catch (Exception e) {
                log.error("调用发送广播失败", e);
            }
        }
        return rtn;
    }

    private static Map<Integer, String> sendDataSingle(HashMap<Integer, String> param, boolean async, ServiceDefine srvDefine) throws Exception {
        param.put(RudpParamDefine.cmd_param_skip_auth, CommonConst.ICE_TOKEN_CODE);
        SocketAddress srvAddress = new InetSocketAddress(InetAddress.getByName(srvDefine.extIp), srvDefine.srvPort);
        if (async) {
            RudpDataUtil.sendDataAsyn(param, srvAddress, null);
        } else {
            return RudpDataUtil.sendDataSync(param, srvAddress, null);
        }
        return null;
    }

    public static void sendGameNotify(Long torid, Long rouid, String type, String userInfo, String roundInfo, String wageInfo) {
        try {
            HashMap<Integer, String> param = new HashMap<>();

            param.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_game_ntf));

            if (torid != null && torid > 0) {
                param.put(RudpParamDefine.cmd_param_to_rid, torid.toString());
            }

            if (rouid != null && rouid > 0) {
                param.put(RudpParamDefine.cmd_param_to_uid, rouid.toString());
            }

            if (roundInfo != null && !"".equals(roundInfo)) {
                param.put(RudpParamDefine.cmd_param_round_info, roundInfo);
            }

            if (wageInfo != null && !"".equals(wageInfo)) {
                param.put(RudpParamDefine.cmd_param_wage_info, wageInfo);
            }

            if (type != null && !"".equals(type)) {
                param.put(RudpParamDefine.cmd_param_type, type);
            }
            if (userInfo != null && !"".equals(userInfo)) {
                param.put(RudpParamDefine.cmd_param_user_info, userInfo);
            }
            param.put(RudpParamDefine.cmd_param_uid, "10000");
            log.info("######发送通知:" + param.toString());
            sendSgsCmd(param, true, 0);

        } catch (Exception e) {
            log.error("发送游戏通知失败", e);
        }

    }

    public static void sendNofity(CommonNotify ntfObj) {
        try {
            HashMap<Integer, String> param = new HashMap<>();

            param.put(RudpParamDefine.cmd_param_cmd_type, ntfObj.getNotifyCmd());
            param.put(RudpParamDefine.cmd_param_type, ntfObj.getNotifyType());
            param.put(RudpParamDefine.cmd_param_text, ntfObj.getNotifyText());
            param.put(RudpParamDefine.cmd_param_uid, ntfObj.getUid().toString());

            if (ntfObj.getNotifyNote() != null && !"".equals(ntfObj.getNotifyNote())) {
                param.put(RudpParamDefine.cmd_param_note, ntfObj.getNotifyNote());
            }

            if (ntfObj.getToDistid() != null && ntfObj.getToDistid().intValue() > 0) {
                param.put(RudpParamDefine.cmd_param_to_dist_id, ntfObj.getToDistid().toString());
            }

            if (ntfObj.getToDeptid() != null && ntfObj.getToDeptid().intValue() > 0) {
                param.put(RudpParamDefine.cmd_param_to_dept_id, ntfObj.getToDeptid().toString());
            }
            if (ntfObj.getToRid() != null && ntfObj.getToRid().intValue() > 0) {
                param.put(RudpParamDefine.cmd_param_to_rid, ntfObj.getToRid().toString());
            }

            if (ntfObj.getToUid() != null && ntfObj.getToUid() > 0) {
                param.put(RudpParamDefine.cmd_param_to_uid, ntfObj.getToUid().toString());
            }

            sendSgsCmd(param, true, 0);

        } catch (Exception e) {
            log.error("发送系统通知失败", e);
        }
    }

    public static void getKickedUser(String rid, long srvId) throws Exception {

        HashMap<Integer, String> req = new HashMap<>();
        req.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_admin_req));
        req.put(RudpParamDefine.cmd_param_rid, rid);
        req.put(RudpParamDefine.cmd_param_admin_cmd, "get_kicked_user");

        SignalCmdUtil.sendSgsCmd(req, true, srvId);
    }

    public static int modifyRoom(long rid, long uid, String cmd, Map<String, String> params, long srvId) throws Exception {

        HashMap<Integer, String> req = new HashMap<>();
        req.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_modify_room));
        req.put(RudpParamDefine.cmd_param_rid, String.valueOf(rid));
        req.put(RudpParamDefine.cmd_param_uid, String.valueOf(uid));
        req.put(RudpParamDefine.cmd_param_subcmd, cmd);//"unlock_kicked_user"

        if (params != null) {
            // add/remove blacklist
            String kickedId = params.get("kickedId");
            if (kickedId != null)
                req.put(RudpParamDefine.cmd_param_kicked_id, kickedId);

            String time = params.get("time");
            if (time != null)
                req.put(RudpParamDefine.cmd_param_time_len, time);

            String play = params.get("play_control");
            if (play != null)
                req.put(RudpParamDefine.cmd_param_play_control, play);

            String msg = params.get("msg_control");
            if (msg != null)
                req.put(RudpParamDefine.cmd_param_msg_control, msg);

            String video = params.get("video_control");
            if (video != null)
                req.put(RudpParamDefine.cmd_param_video_control, video);

            String enter = params.get("enter_mode");
            if (enter != null)
                req.put(RudpParamDefine.cmd_param_enter_mode, enter);

            String password = params.get("password");
            if (password != null)
                req.put(RudpParamDefine.cmd_param_password, password);

        }
        Map<Integer, String> map = SignalCmdUtil.sendSgsCmd(req, false, srvId);
        return checkMap(map);
    }

    private static int checkMap(Map<Integer, String> map) throws Exception {

        if(map == null)
            return 0;
        else{
            log.error("##########调用返回"+map);


            if (map != null && map.containsKey(RudpParamDefine.cmd_param_code)) {
                return Integer.parseInt(map.get(RudpParamDefine.cmd_param_code));
            }
            return -1;
        }

    }

    public static void refreshData(String[] rid, String[] uid, String adminCmd) throws Exception {

        HashMap<Integer, String> req = new HashMap<>();
        req.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_admin_req));
        // refresh_data ：刷新im-sgs  refresh_user 刷新频道
        req.put(RudpParamDefine.cmd_param_admin_cmd, adminCmd);
        if (rid != null && rid.length > 0) {
            for (String id : rid) {
                req.put(RudpParamDefine.cmd_param_rid, id);
                SignalCmdUtil.sendSgsCmd(req, true, 0);
            }
        }
        if (uid != null && uid.length > 0) {
            for (String id : uid) {
                req.put(RudpParamDefine.cmd_param_uid, id);
                SignalCmdUtil.sendImsCmd(req, false, 0);
            }
        }

    }

    /**
     * 刷新频道数据
     * @param uid
     * @throws Exception
     */
    public static void refreshChannelData(String[] uid) throws Exception {
        HashMap<Integer, String> req = new HashMap<>();
        req.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_admin_req));
        req.put(RudpParamDefine.cmd_param_admin_cmd, "refresh_user");
        if (uid != null && uid.length > 0) {
            for (String id : uid) {
                req.put(RudpParamDefine.cmd_param_uid, id);
                SignalCmdUtil.sendImsCmd(req, true, 0);
            }
        }

    }

    /**
     * 用户剔出房间
     * @param rid
     * @param uids
     * @param adminCmd
     * @throws Exception
     */
    public static void forceOutRoom(String rid, String[] uids, String adminCmd) throws Exception {
        HashMap<Integer, String> req = new HashMap<>();
        req.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_admin_req));
        req.put(RudpParamDefine.cmd_param_admin_cmd, adminCmd);
        req.put(RudpParamDefine.cmd_param_code,"0");
        if (rid != null && uids.length > 0) {
            req.put(RudpParamDefine.cmd_param_rid, rid);
            for (String uid : uids) {
                req.put(RudpParamDefine.cmd_param_kicked_id,uid);
                SignalCmdUtil.sendSgsCmd(req, true, 0);
            }
        }
    }


    public static int mediaRecord(long rid, long uid,String refId, String cmd) throws Exception {
        HashMap<Integer, String> req = new HashMap<>();
        req.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_admin_req));
        req.put(RudpParamDefine.cmd_param_subcmd, cmd);
        req.put(RudpParamDefine.cmd_param_rid, String.valueOf(rid));
        req.put(RudpParamDefine.cmd_param_uid, String.valueOf(uid));
        req.put(RudpParamDefine.cmd_param_ref_id, refId);
//        req.put(RudpParamDefine.cmd_param_video_id, String.valueOf(videoId));
//        req.put(RudpParamDefine.cmd_param_audio_id, String.valueOf(audioId));
//        req.put(RudpParamDefine.cmd_param_mds_info, mdsServers);
        //2016-11-24 刘胜修改接口，这些参数免填写
        req.put(RudpParamDefine.cmd_param_time_len, "8");
        req.put(RudpParamDefine.cmd_param_count, "3");

        Map<Integer, String> map = SignalCmdUtil.sendShowCmd(req, false, -1);
        return checkMap(map);
    }


    public static int mediaRecord(long rid, long uid, String cmd, long videoId, long audioId, String mdsServers) throws Exception {
        HashMap<Integer, String> req = new HashMap<>();
        req.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_admin_req));
        req.put(RudpParamDefine.cmd_param_subcmd, cmd);
        req.put(RudpParamDefine.cmd_param_rid, String.valueOf(rid));
        req.put(RudpParamDefine.cmd_param_uid, String.valueOf(uid));
//        req.put(RudpParamDefine.cmd_param_video_id, String.valueOf(videoId));
//        req.put(RudpParamDefine.cmd_param_audio_id, String.valueOf(audioId));
//        req.put(RudpParamDefine.cmd_param_mds_info, mdsServers);
        //2016-11-24 刘胜修改接口，这些参数免填写
        req.put(RudpParamDefine.cmd_param_time_len, "8");
        req.put(RudpParamDefine.cmd_param_count, "3");

        Map<Integer, String> map = SignalCmdUtil.sendShowCmd(req, false, -1);
        return checkMap(map);
    }

    public static int addMember(String rid, String uid, String memberId, String memberName, String membership, long srvId) throws Exception {

        HashMap<Integer, String> req = new HashMap<>();

        req.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_modify_room));
        req.put(RudpParamDefine.cmd_param_rid, rid);
        req.put(RudpParamDefine.cmd_param_uid, uid);
        req.put(RudpParamDefine.cmd_param_right, membership);
        req.put(RudpParamDefine.cmd_param_dest_id, memberId);
        req.put(RudpParamDefine.cmd_param_dest_name, memberName);
        req.put(RudpParamDefine.cmd_param_subcmd, "add_member");

        Map<Integer, String> map = SignalCmdUtil.sendSgsCmd(req, false, srvId);
        return checkMap(map);
    }

    public static int dismissRoom(String rid, long srvId) throws Exception {
        HashMap<Integer, String> notify = new HashMap<>();
        notify.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_admin_req));
        notify.put(RudpParamDefine.cmd_param_admin_cmd, "dismiss_room");
        notify.put(RudpParamDefine.cmd_param_rid, rid);
        Map<Integer, String> map = SignalCmdUtil.sendSgsCmd(notify, false, srvId);
        return checkMap(map);
    }

    /** 收费房间欠费 */
    public static int kickUser(String rid, String uid, boolean ims, long srvId) throws Exception {
        HashMap<Integer, String> notify = new HashMap<>();
        notify.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_admin_req));
        notify.put(RudpParamDefine.cmd_param_admin_cmd, "force_out");
        notify.put(RudpParamDefine.cmd_param_uid, "10000");
        notify.put(RudpParamDefine.cmd_param_code, "6074");
        notify.put(RudpParamDefine.cmd_param_rid, rid);
        notify.put(RudpParamDefine.cmd_param_kicked_id, uid);

        Map<Integer, String> map = SignalCmdUtil.sendSgsCmd(notify, false, srvId);
        if (ims)
            map = SignalCmdUtil.sendImsCmd(notify, true, srvId);
        return checkMap(map);
    }

    public static int kickRoomUser(long rid, long uid, String type, String kickedId, long srvId) throws Exception {
        HashMap<Integer, String> notify = new HashMap<>();
        notify.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_admin_req));
        notify.put(RudpParamDefine.cmd_param_admin_cmd, "kick_user");

        notify.put(RudpParamDefine.cmd_param_rid, String.valueOf(rid));
        notify.put(RudpParamDefine.cmd_param_uid, String.valueOf(uid));
        notify.put(RudpParamDefine.cmd_param_kicked_id, kickedId);
        notify.put(RudpParamDefine.cmd_param_type, type);
        notify.put(RudpParamDefine.cmd_param_time_len, "1000000");

        Map<Integer, String> map = SignalCmdUtil.sendSgsCmd(notify, false, srvId);
        return checkMap(map);
    }

    public static String genMsgId(long uid, long destId, long timestamp) {
        StringBuilder msgidstr = new StringBuilder();
        long tmpid = (uid + destId) % 1000000;
        if (tmpid < 100000) {
            tmpid += 100000;
        }
        msgidstr.append(tmpid);
        long tmp = timestamp % 1000000;
        if (tmp < 100000) {
            tmp += 100000;
        }
        msgidstr.append(tmp);
        msgid++;
        if (msgid < 1000) {
            msgidstr.append(1000 + msgid);
        } else {
            msgidstr.append(msgid);
            msgid = 0;
        }
        return msgidstr.toString();
    }

    /**
     * 发送消息（线程）
     *
     * @throws Exception
     */
    public static void sendMsg(long uid, long destId, String message,
                               String msgType) throws Exception {

        try {
            if (imsDeploys == null || imsDeploys.size() <= 0) {
                loadImsDeploys();
            }
            if (imsDeploys == null || imsDeploys.size() <= 0) {
                throw new Exception("服务列表配置出错，请检查NMC-ImsSrv");
            }
            HashMap<Integer, String> params = new HashMap<Integer, String>();
            if (uid == 0) {
                uid = 10000;// 系统ID
            }
            long curtime = System.currentTimeMillis();
            params.put(RudpParamDefine.cmd_param_via, "bcs");
            params.put(RudpParamDefine.cmd_param_cmd_type,
                    String.valueOf(RudpCmdDefine.cmd_type_send_msg));
            params.put(RudpParamDefine.cmd_param_uid, String.valueOf(uid));
            params.put(RudpParamDefine.cmd_param_snd_id, String.valueOf(uid));
            params.put(RudpParamDefine.cmd_param_dest_id,
                    String.valueOf(destId));
            params.put(RudpParamDefine.cmd_param_rcv_id, String.valueOf(destId));
            params.put(RudpParamDefine.cmd_param_mid, SignalCmdUtil.genMsgId(uid, destId, curtime));
            params.put(RudpParamDefine.cmd_param_time, String.valueOf(curtime));
            params.put(RudpParamDefine.cmd_param_send_type, msgType);
            params.put(RudpParamDefine.cmd_param_msg, message);
            params.put(RudpParamDefine.cmd_param_skip_auth, CommonConst.ICE_TOKEN_CODE);

            boolean success = false;
            for (Iterator<ServiceDefine> iter = imsDeploys.iterator(); iter.hasNext(); ) {
                ServiceDefine srvDefine = iter.next();
                try {
                    SocketAddress srvAddress = new InetSocketAddress(
                            InetAddress.getByName(srvDefine.extIp),
                            srvDefine.srvPort);
                    RudpDataUtil.sendDataAsyn(params, srvAddress, null);
                    success = true;
                } catch (Exception e) {
                    log.error(JSON.toJSONString(srvDefine) + " failed.", e);
                }
            }
            if (!success) {
                throw new Exception("信息发送失败");
            }
        } catch (Exception e) {
            log.error("IMS消息发送失败：", e);
        }
    }

    /**
     * 发送临时呼叫IM消息
     * @param uid
     * @param senduid
     * @param destId
     * @param message
     * @param msgType
     * @param channelName
     * @throws Exception
     */
    public static void sendMsgByTempCall(long uid,long senduid, long destId, String message,
                                       String msgType, long msgId, String channelName) throws Exception {
        try {
            if (imsDeploys == null || imsDeploys.size() <= 0) {
                loadImsDeploys();
            }
            if (imsDeploys == null || imsDeploys.size() <= 0) {
                throw new Exception("服务列表配置出错，请检查NMC-ImsSrv");
            }
            HashMap<Integer, String> params = new HashMap<Integer, String>();
            if (uid == 0) {
                uid = 10000;// 系统ID
            }
            long curtime = System.currentTimeMillis();
            params.put(RudpParamDefine.cmd_param_via, "bcs");
            params.put(RudpParamDefine.cmd_param_cmd_type, String.valueOf(RudpCmdDefine.cmd_type_send_msg));
            params.put(RudpParamDefine.cmd_param_uid, String.valueOf(uid));
            params.put(RudpParamDefine.cmd_param_snd_id, String.valueOf(senduid));
            params.put(RudpParamDefine.cmd_param_dest_id,
                    String.valueOf(destId));
            params.put(RudpParamDefine.cmd_param_rcv_id, String.valueOf(destId));
            params.put(RudpParamDefine.cmd_param_mid, String.valueOf(msgId));
            params.put(RudpParamDefine.cmd_param_time, String.valueOf(curtime));
            params.put(RudpParamDefine.cmd_param_send_type, msgType);
            params.put(RudpParamDefine.cmd_param_msg, message);
            params.put(RudpParamDefine.cmd_param_name, channelName);
            params.put(RudpParamDefine.cmd_param_skip_auth, CommonConst.ICE_TOKEN_CODE);

            boolean success = false;
            for (Iterator<ServiceDefine> iter = imsDeploys.iterator(); iter.hasNext(); ) {
                ServiceDefine srvDefine = iter.next();
                try {
                    SocketAddress srvAddress = new InetSocketAddress(
                            InetAddress.getByName(srvDefine.extIp),
                            srvDefine.srvPort);
                    RudpDataUtil.sendDataAsyn(params, srvAddress, null);
                    success = true;
                } catch (Exception e) {
                    log.error(JSON.toJSONString(srvDefine) + " failed.", e);
                }
            }
            if (!success) {
                throw new Exception("信息发送失败");
            }
        } catch (Exception e) {
            log.error("IMS消息发送失败：", e);
        }
    }

    /**
     * 带消息id发送可靠消息
     * @param uid 发送人
     * @param senduid 10000
     * @param destId 收消息人
     * @param message 消息内容
     * @param msgType 消息类型
     * @param msgId 消息ID
     * @throws Exception
     */
    public static void sendMsgByUMsgId(long uid,long senduid, long destId, String message,
                                      String msgType,long msgId) throws Exception {
        try {
            if (imsDeploys == null || imsDeploys.size() <= 0) {
                loadImsDeploys();
            }
            if (imsDeploys == null || imsDeploys.size() <= 0) {
                throw new Exception("服务列表配置出错，请检查NMC-ImsSrv");
            }
            HashMap<Integer, String> params = new HashMap<Integer, String>();
            if (uid == 0) {
                uid = 10000;// 系统ID
            }
            long curtime = System.currentTimeMillis();
            params.put(RudpParamDefine.cmd_param_via, "bcs");
            params.put(RudpParamDefine.cmd_param_cmd_type,
                    String.valueOf(RudpCmdDefine.cmd_type_send_msg));
            params.put(RudpParamDefine.cmd_param_uid, String.valueOf(uid));
            params.put(RudpParamDefine.cmd_param_snd_id, String.valueOf(senduid));
            params.put(RudpParamDefine.cmd_param_dest_id,
                    String.valueOf(destId));
            params.put(RudpParamDefine.cmd_param_rcv_id, String.valueOf(destId));
            params.put(RudpParamDefine.cmd_param_mid, String.valueOf(msgId));
            params.put(RudpParamDefine.cmd_param_time, String.valueOf(curtime));
            params.put(RudpParamDefine.cmd_param_send_type, msgType);
            params.put(RudpParamDefine.cmd_param_msg, message);
            params.put(RudpParamDefine.cmd_param_skip_auth, CommonConst.ICE_TOKEN_CODE);

            boolean success = false;
            for (Iterator<ServiceDefine> iter = imsDeploys.iterator(); iter.hasNext(); ) {
                ServiceDefine srvDefine = iter.next();
                try {
                    SocketAddress srvAddress = new InetSocketAddress(
                            InetAddress.getByName(srvDefine.extIp),
                            srvDefine.srvPort);
                    RudpDataUtil.sendDataAsyn(params, srvAddress, null);
                    success = true;
                } catch (Exception e) {
                    log.error(JSON.toJSONString(srvDefine) + " failed.", e);
                }
            }
            if (!success) {
                throw new Exception("信息发送失败");
            }
        } catch (Exception e) {
            log.error("IMS消息发送失败：", e);
        }
    }

    /**
     * 发送消息（线程）包含msgId
     *
     * @throws Exception
     */
    public static void sendMsgByMsgId(long uid, long destId, String message,
                               String msgType,long msgId) throws Exception {

        try {
            if (imsDeploys == null || imsDeploys.size() <= 0) {
                loadImsDeploys();
            }
            if (imsDeploys == null || imsDeploys.size() <= 0) {
                throw new Exception("服务列表配置出错，请检查NMC-ImsSrv");
            }
            HashMap<Integer, String> params = new HashMap<Integer, String>();
            if (uid == 0) {
                uid = 10000;// 系统ID
            }
            long curtime = System.currentTimeMillis();
            params.put(RudpParamDefine.cmd_param_via, "bcs");
            params.put(RudpParamDefine.cmd_param_cmd_type,
                    String.valueOf(RudpCmdDefine.cmd_type_send_msg));
            params.put(RudpParamDefine.cmd_param_uid, String.valueOf(uid));
            params.put(RudpParamDefine.cmd_param_snd_id, String.valueOf(uid));
            params.put(RudpParamDefine.cmd_param_dest_id,
                    String.valueOf(destId));
            params.put(RudpParamDefine.cmd_param_rcv_id, String.valueOf(destId));
            params.put(RudpParamDefine.cmd_param_mid, String.valueOf(msgId));
            params.put(RudpParamDefine.cmd_param_time, String.valueOf(curtime));
            params.put(RudpParamDefine.cmd_param_send_type, msgType);
            params.put(RudpParamDefine.cmd_param_msg, message);
            params.put(RudpParamDefine.cmd_param_skip_auth, CommonConst.ICE_TOKEN_CODE);

            boolean success = false;
            for (Iterator<ServiceDefine> iter = imsDeploys.iterator(); iter.hasNext(); ) {
                ServiceDefine srvDefine = iter.next();
                try {
                    SocketAddress srvAddress = new InetSocketAddress(
                            InetAddress.getByName(srvDefine.extIp),
                            srvDefine.srvPort);
                    RudpDataUtil.sendDataAsyn(params, srvAddress, null);
                    success = true;
                } catch (Exception e) {
                    log.error(JSON.toJSONString(srvDefine) + " failed.", e);
                }
            }
            if (!success) {
                throw new Exception("信息发送失败");
            }
        } catch (Exception e) {
            log.error("IMS消息发送失败：", e);
        }
    }

    public static void sengUpdateCmd(long uid) throws Exception {
        try {
            if (imsDeploys == null || imsDeploys.size() <= 0) {
                loadImsDeploys();
            }
            if (imsDeploys == null || imsDeploys.size() <= 0) {
                throw new Exception("服务列表配置出错，请检查NMC-ImsSrv");
            }

            HashMap<Integer, String> params = new HashMap<Integer, String>();
            long curtime = System.currentTimeMillis();
            params.put(RudpParamDefine.cmd_param_via, "bcs");
            params.put(RudpParamDefine.cmd_param_cmd_type,
                    String.valueOf(RudpCmdDefine.cmd_type_send_msg));
            params.put(RudpParamDefine.cmd_param_uid, "10000");
            params.put(RudpParamDefine.cmd_param_snd_id, "10000");
            params.put(RudpParamDefine.cmd_param_rcv_id, String.valueOf(uid));
            params.put(RudpParamDefine.cmd_param_dest_id, String.valueOf(uid));
            params.put(RudpParamDefine.cmd_param_msg, "@update@");
            params.put(RudpParamDefine.cmd_param_mid, SignalCmdUtil.genMsgId(10000, 10000, curtime));
            params.put(RudpParamDefine.cmd_param_time, String.valueOf(curtime));
            params.put(RudpParamDefine.cmd_param_skip_auth, CommonConst.ICE_TOKEN_CODE);
            boolean success = false;
            for (Iterator<ServiceDefine> iter = imsDeploys.iterator(); iter.hasNext(); ) {
                ServiceDefine srvDefine = iter.next();
                try {
                    SocketAddress srvAddress = new InetSocketAddress(
                            InetAddress.getByName(srvDefine.extIp),
                            srvDefine.srvPort);
                    RudpDataUtil.sendDataAsyn(params, srvAddress, null);
                    success = true;
                } catch (Exception e) {
                    log.error(JSON.toJSONString(srvDefine) + " failed.", e);
                }
            }
            if (!success) {
                throw new Exception("信息发送失败");
            }
        } catch (Exception e) {
            log.error("IMS消息发送失败：", e);
        }
    }

    public static void init(int port) throws Exception {
        String hostname = "0.0.0.0";
        InetAddress address = InetAddress.getByName(hostname);
        SocketAddress socketAddress = new InetSocketAddress(address, port);
        RudpDataUtil.initSocket(socketAddress);
        RudpSendresSrvImpl dealsrv = new RudpSendresSrvImpl();

        // 注入业务处理线程池
        BlockingQueue recvqueue = new ArrayBlockingQueue(800);
        ExecutorService respExec = new ThreadPoolExecutor(10, 10, 10, TimeUnit.MINUTES, recvqueue, new ThreadPoolExecutor.DiscardPolicy());
        //ExecutorService respExec = Executors.newFixedThreadPool(5);
        RudpDataUtil.initBusiObj(respExec, dealsrv, null, 1);

        try {
            RudpSendDataManager sendDataManager = new RudpSendDataManager();
            sendDataManager.start();
            log.error("发送数据管理线程启动成功");
        } catch (Exception e) {
            throw new Exception("消息发送数据处理线程启动失败");
        }

        try {
            RudpDataUtil.startReceiver();
        } catch (Exception e) {
            throw new Exception("消息接受线程启动失败");
        }

        try {
            RudpReceiveDataManager dataManager = new RudpReceiveDataManager();
            dataManager.start();
            log.error("接受数据管理线程启动成功");
        } catch (Exception e) {
            throw new Exception("接受数据管理线程启动失败");
        }

    }

    public static void main(String[] args) throws Exception {
        /*String hostname = "0.0.0.0";
        InetAddress address = InetAddress.getByName(hostname);
        SocketAddress socketAddress = new InetSocketAddress(address, 18722);
        RudpDataUtil.initSocket(socketAddress);*/

        //SignalCmdUtil.sendMsg(10000l, 300000010, "4000000", GlobalConstant.MSG_TYPE_CALL);
        //SignalCmdUtil.sendMsg(10000l, 300000001, "4000000", GlobalConstant.MSG_TYPE_CALL);
        //SignalCmdUtil.sendMsg(10000l, 300000002, "4000000", GlobalConstant.MSG_TYPE_CALL);
        //SignalCmdUtil.sengUpdateCmd(10000);
        /*CacheManagerRedis redis = CacheManagerRedis.getWebInstance();
        Set<String> sgss = redis.smembers(RedisKey.Service.SERVICE_CFG, "sgs");
        for (String sgs : sgss) {
            String deploy = redis.getString(sgs);
            log.error("###########" + deploy);
        }*/

        /*StringBuilder notifyinfo = new StringBuilder();
        CommonNotify notify2 = new CommonNotify();
        notify2.setNotifyCmd(String.valueOf(RudpCmdDefine.cmd_type_broadcast));
        notify2.setNotifyType("lc_stat");
        notifyinfo.append("用户冉建新上报了资源信息，资源说明：拍照留下证据");
        notify2.setUid(10000l);
        notify2.setNotifyText(notifyinfo.toString());
        notify2.setToRid(30000001l);
        SignalCmdUtil.sendNofity(notify2);
        SignalCmdUtil.sendMsgByUMsgId(300000010,10000,300000001,"测试",GlobalConstant.MSG_TYPE_BROAD,1);
        */
        SignalCmdUtil.init(1789);
        String[] uids={"300000010"};
        SignalCmdUtil.refreshData(null, uids, "refresh_user");
    }

}
